package cn.edu.neu.lab603.cloudeval.strategy.policy

import cn.edu.neu.lab603.cloudeval.entity.{DataCenter, PhysicalMachine => Host, VirtualMachine => VM}

import scala.collection.{SeqView, mutable}

/** 迁移
  *
  * Created by yfwz100 on 2016/11/9.
  */
object MigrationDef {

  implicit final class RichHost(private val host: Host) extends AnyVal {
    def getMigratableVMs: SeqView[VM, Seq[VM]] = host.getVMList.view.filter(_.getStatus == VM.Status.ON)

    def isIdle: Boolean = host.getVMList.isEmpty

    def getRemainSpecRes: mutable.HashMap[String, Int] = {
      val ret = mutable.HashMap[String, Int](host.capacity.toSeq: _*)
      host.getVMList.foldLeft(ret) { (c, it) =>
        it.getSpecResMap.foreach { p =>
          c(p._1) = c.getOrElse(p._1, 0) - p._2
        }
        c
      }
    }

    def getUtilizationHistory: Array[Double] = {
      val vmUtils = host.getVMList.map { vm =>
        val mips = vm.getSpecResMap("mips")
        vm.getUtilizationHistory("mips").map(_ * mips)
      }
      val hostMips = host.capacity("mips")
      val utilizationHistory = Array.ofDim[Double](vmUtils.map(_.size).min)
      for (v <- vmUtils) {
        val s = v.size - 1
        for (i <- utilizationHistory.indices) {
          utilizationHistory(i) += v(s - i) / hostMips
        }
      }
      utilizationHistory
    }

    def wrap(vm: VM): Host = {
      null
    }
  }

  implicit final class RichDataCenter(private val dataCenter: DataCenter) extends AnyVal {

    def getRunningHost: SeqView[Host, Seq[Host]] = dataCenter.pmList.view.filter(_.getStatus == Host.Status.ON)
  }

}
